package com.klikmee.sms.core.base.handlers;

import java.text.MessageFormat;

import org.apache.log4j.Logger;

import com.klikmee.sms.core.base.util.DeliveryReports;
import com.klikmee.sms.core.base.util.States;
import com.klikmee.sms.core.model.IncomingMessage;
import com.klikmee.sms.core.model.OutgoingMessage;
import com.klikmee.sms.core.model.PaymentInvoice;

public class ChargedMessageDeliveryReportHandler extends AbstractDeliveryHandler<OutgoingMessage> {

	/**
	 * Logger instance
	 */
	private Logger logger = Logger.getLogger( ChargedMessageDeliveryReportHandler.class );
	
	@Override
	public void handle(OutgoingMessage outgoingMessage) {
		// get payment invoice
		PaymentInvoice paymentInvoice = outgoingMessage.getPaymentInvoiceList().iterator().next();

		// get incoming message id
		IncomingMessage incomingMessage = paymentInvoice.getIncomingMessage();

		Integer deliveryStatus = outgoingMessage.getDeliveryStatus();

		// switch delivery status trough all known statuses

		switch (deliveryStatus) {

		// first check if message is delivered
		case DeliveryReports.DELIVERED:

			// push incoming message state
			switch (incomingMessage.getState()) {
			case States.IncommingMessage.BAD_SYNTAX_NOTIFICATION_SENT:
				incomingMessage.setState( States.IncommingMessage.BAD_SYNTAX_USER_NOTIFIED );
				logger.debug( MessageFormat.format( "Pushed incoming bad syntax message state to [{0}]", incomingMessage.getState()) );
				break;

			case States.IncommingMessage.BAD_SEMANTIC_NOTIFICATION_SENT:
				incomingMessage.setState( States.IncommingMessage.BAD_SEMANTIC_USER_NOTIFIED );
				logger.debug( MessageFormat.format( "Pushed incoming bad semantic message state to [{0}]", incomingMessage.getState()) );

			case States.IncommingMessage.SERVICE_NOT_AVAILABLE_NOTIFICATION_SENT:
				incomingMessage.setState( States.IncommingMessage.SERVICE_NOT_AVAILABLE_USER_NOTIFIED );
				logger.debug( MessageFormat.format( "Pushed incoming service not availabe message state to [{0}]", incomingMessage.getState()) );

			default:
				break;
			}

			// push outgoing message
			outgoingMessage.setState( States.OutgoingMessage.DELIVERED );
			
			// push payment invoice
			paymentInvoice.setState( States.PaymentInvoice.CHARGED );
			logger.debug( MessageFormat.format( "Pushed outgoing message state to [{0}]", outgoingMessage.getState()));
			logger.debug( MessageFormat.format( "Pushed payment invoice state to [{0}]", paymentInvoice.getState()));
			break;

		// check for failed delivery if user has insufficient funds
		case DeliveryReports.Telenor.NOCREDIT:
			// TODO: check if this is the plase to send vip info message to user
			// e.g. We are sorry but you don't have sufficient funds.
			outgoingMessage.setState( States.OutgoingMessage.UNDELIVERED );

			paymentInvoice.setState( States.PaymentInvoice.INSUFFICIENT_FUNDS );

			break;

		// all other statuses

		default:
			outgoingMessage.setState( States.OutgoingMessage.UNDELIVERED );
			paymentInvoice.setState( States.PaymentInvoice.UNDELIVERED_SERVICE );
			
			logger.debug( MessageFormat.format( "Defaulted outgoing message state to  [{0}]", outgoingMessage.getState()));

		}

		// merge changes, OM & IM will be cascaded
		paymentInvoiceDAO.edit( paymentInvoice );		
	}
	
	@Override
	public String toString() {
		return "Charged delivery report handler" + super.toString();
	}
}
